package reflectiondemo;

import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class TestDriverReflect {

    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        System.out.println("=======反射工具类：Class工具类========================");
        System.out.println("==Class clazz1 = Class.forName" +
                "(\"reflectiondemo.Student\");//仓库文件的路径===");
        test01();
        System.out.println();
        System.out.println("=======反射工具类：Constructor工具类============");
        System.out.println("==Constructor<Student> constructor =\n" +
                "                    clazz.getDeclaredConstructor(String.class,String.class,Double.class);==");
        test02();
        System.out.println();
        System.out.println("=======反射工具类：Field工具类============");
        System.out.println("===Field field = classz.getDeclaredField(\"stuName\");====");
        test03();
        System.out.println();
        System.out.println("=======反射工具类：Field工具类============");
        System.out.println("== Method method = classz.getDeclaredMethod" +
                "(\"doStuding\",String.class);==");
        test04();
        System.out.println();
    }

    /**
     * 反射工具类：Field工具类
     */
    public static void test04(){
        //(3)实例对象：getClass方法
        Student student = new Student();
        Class classz = student.getClass();
        try {
            //指定获取一个名字的方法对象

            Method method = classz.getDeclaredMethod("doStuding",String.class);
            //使用invoke调用method对象，让该方法对象动态执行起来
            //调用student的含有地址的doStuding的方法
            method.invoke(student,"xsuscscbs");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 反射工具类：Field工具类
     */
    public static void test03() throws NoSuchFieldException {
    //(3)实例对象：getClass方法
        Student student  = new Student();
        Class classz = student.getClass();//继承自Object类的方法
        try{
            //获取一个指定名字的属性对象
            Field field = classz.getDeclaredField("stuName");
            //设置属性可以操作私有属性
            field.setAccessible(true);
            //调用属性对象的set方法，给属性对象进行设值，需要绑定该属性来自的实例对象
            field.set(student,"sxsabxsb");
            System.out.println(student);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    /**
     * 反射工具类：Constructor工具类
     */
    public  static  void test02(){
        //获取类 ，描述类class的三种途径
        //（1）类名class
        //Student类
        Class<Student> clazz = Student.class;//Student类

        try{
            //获取类的构造方法
            Constructor<Student> constructor =
                    clazz.getDeclaredConstructor(String.class,String.class,Double.class);
            //调用构造方法对象的newInstance方法创建一个实例对象
            Student student = constructor.newInstance("zanss","10010",90);
            System.out.println("通过构造方法对象获取的实例变量");
            System.out.println(student);

        } catch (Exception e){
            e.printStackTrace();
        }
        /*catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }*/
    }

    /**
     * 反射工具类：class工具类
     */
    public static void test01() throws ClassNotFoundException {
        //获取类 ，描述类class的三种途径
        //（1）类名class
        //Student类
        Class<Student> clazz = Student.class;//Student类
        //(2)class的forName静态方法
        try{
            //forName传输Student类
            Class clazz1 = Class.forName("reflectiondemo.Student");//仓库文件的路径
            System.out.println("clazz == clazz1:"+(clazz == clazz1));
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }
        //(3)实例对象，getClas方法
        Student student = new Student();
        //Object类----继承Student类
        Class clazz2 = student.getClass();//继承自Object类的方法

        System.out.println("clazz == clazz2:"+(clazz == clazz2));

        try{
            //通过Class获取这个类的实例对象
            Student student1 = clazz.newInstance();//等价于new
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }
}
